package com.demo.test;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.amap.api.location.AMapLocationClient;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.demo.test.databinding.ActivityMainBinding;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements AMap.OnMyLocationChangeListener, GeocodeSearch.OnGeocodeSearchListener {

    private String TAG = "MainActivity";

    private ActivityMainBinding binding;

    private AMap aMap;

    private GeocodeSearch geocodeSearch;

    private Marker positionMarker;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        AMapLocationClient.updatePrivacyAgree(this.getApplicationContext(), true);
        AMapLocationClient.updatePrivacyShow(this.getApplicationContext(), true, true);
        binding.map.onCreate(savedInstanceState);
        if (this.hasPermission()) {
            this.init();
        }
    }

    private void init() {
        if (aMap == null) {
            aMap = binding.map.getMap();
            setUpMap();
        }
    }

    private void setUpMap() {

        // 地理编码搜索
        try {
            geocodeSearch = new GeocodeSearch(this);
            geocodeSearch.setOnGeocodeSearchListener(this);
        } catch (AMapException e) {
            Log.e(TAG, "地址描述搜索初始化失败", e);
        }

        MyLocationStyle mapStyle = new MyLocationStyle();
        mapStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
        mapStyle.showMyLocation(false);
        aMap.setMyLocationStyle(mapStyle);
        aMap.setOnMyLocationChangeListener(this);
        aMap.setOnMapLoadedListener(() -> {
            LatLng latLng = aMap.getCameraPosition().target;
            Point screenPosition = aMap.getProjection().toScreenLocation(latLng);
            positionMarker = aMap.addMarker(
                    new MarkerOptions()
                            .anchor(0.5f, 1.0f)
                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.poi_marker_pressed))
                            .setInfoWindowOffset(0, -10)
                            .visible(true)
            );
            //设置Marker在屏幕上,不跟随地图移动
            positionMarker.setPositionByPixels(screenPosition.x, screenPosition.y);
            positionMarker.setZIndex(1);
        });
        aMap.setInfoWindowAdapter(new AMap.InfoWindowAdapter() {
            @Override
            public View getInfoWindow(Marker marker) {
                TextView textView = new TextView(MainActivity.this);
                textView.setBackgroundColor(0xFF888888);
                textView.setTextColor(0xffffffff);
                textView.setPadding(8, 8, 8, 8);
                textView.setText(marker.getTitle());
                return textView;
            }

            @Override
            public View getInfoContents(Marker marker) {
                return null;
            }
        });

        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false

        // 设置地图的手势监听
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
                // ignored
            }

            @Override
            public void onCameraChangeFinish(CameraPosition position) {
                doLatLngSearch(position.target.latitude, position.target.longitude);
            }
        });
    }


    @Override
    public void onMyLocationChange(Location location) {
        double lat = location.getLatitude();
        double lng = location.getLongitude();
        aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 16.F));
        this.doLatLngSearch(lat, lng);
    }

    private void doLatLngSearch(double lat, double lng) {
        if (geocodeSearch != null) {
            RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(lat, lng), 200, GeocodeSearch.AMAP);
            geocodeSearch.getFromLocationAsyn(query);
        }
    }

    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int code) {
        if (code != 1000) {
            Log.e(TAG, "地理逆编码出错, code = " + code);
            return;
        }
        RegeocodeAddress address = result.getRegeocodeAddress();
        String title = this.getLocationTitle(address);
        this.setMarkerTitle(title);
        RegeocodeQuery query = result.getRegeocodeQuery();
        LatLonPoint currentPoint = query.getPoint();
        this.moveCameraToLatLng(currentPoint.getLatitude(), currentPoint.getLongitude());
        Log.i(TAG, "选择的地址为: " + address.getFormatAddress());
        binding.tvTitle.setText(title);
    }

    private void setMarkerTitle(String title) {
        if (this.positionMarker != null) {
            this.positionMarker.setTitle(title);
            this.positionMarker.showInfoWindow();
        }
    }

    private void moveCameraToLatLng(double lat, double lng) {
        aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(lat, lng)));
    }

    private String getLocationTitle(RegeocodeAddress address) {
        String province = address.getProvince();
        String city = address.getCity();
        String district = address.getDistrict();
        String township = address.getTownship();
        return address.getFormatAddress()
                .replaceFirst(province, "")
                .replaceFirst(city, "")
                .replaceFirst(district, "")
                .replaceFirst(township, "");
    }

    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

    }

    @Override
    protected void onResume() {
        super.onResume();
        binding.map.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        binding.map.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        binding.map.onSaveInstanceState(outState);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        binding.map.onDestroy();
    }

    private boolean hasPermission() {
            List<String> permissions = new ArrayList<>();
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
                permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_MEDIA_LOCATION)) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    permissions.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
                }
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS)) {
                permissions.add(Manifest.permission.WRITE_SETTINGS);
            }

            if (permissions.size() != 0) {
                ActivityCompat.requestPermissions(this, permissions.toArray(new String[0]), 100);
                return false;
            }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (permissions.length > 0) {
            this.init();
        }
    }
}